from collections import defaultdict
from typing import Dict, List
from common.enum.stock_category_enum import StockCategoryEnum
from service.das.stock_monitor_das import AntMonitorStock, StockDas
from views.template_page_view import TableDataDto


class StockViewService:

    def query_stocks_by_category_and_sort(
        self, category, sort_by="focus_level"
    ) -> List[AntMonitorStock]:
        """
        查询股票，按分类过滤并根据指定字段排序。
        :param category: 要查询的股票分类（例如 StockCategoryEnum.UNIQUE）。
        :param sort_by: 排序字段，"focus_level" 或 "risk_level"。
        :return: 查询结果列表。
        """
        stock_das = StockDas()

        # 校验排序字段是否有效
        if sort_by not in ["focus_level", "risk_level"]:
            raise ValueError(
                "Invalid sort_by value. Use 'focus_level' or 'risk_level'."
            )

        return stock_das.get_stocks_by_category(category, sort_by, 10)

    def exchange_stock_table_info(
        self, stock_list: List[AntMonitorStock]
    ) -> TableDataDto:
        """
        根据分类和排序方式查询股票数据，并返回格式化的报表数据。
        :param category: 股票分类枚举值（例如 StockCategoryEnum.UNIQUE）
        :param sort_by: 排序字段，"focus_level" 或 "risk_level"
        :return: TableDataDto 对象
        """
        # 格式化股票数据为表格形式
        table_data = []
        for stock in stock_list:
            stock_code = stock.stock_code
            stock_name = stock.stock_name
            stock_plates = stock.stock_plates
            stock_current_price = (
                f"{stock.monitor_current_price:.2f}"
                if stock.monitor_current_price is not None
                else "N/A"
            )
            monitor_income_ratio = (
                f"{stock.monitor_income_ratio:.2f}%"
                if stock.monitor_income_ratio is not None
                else "N/A"
            )
            stock_risk_level = self.get_risk_level_description(stock.stock_risk_level)
            stock_focus_level = self.get_focus_level_description(
                stock.stock_focus_level
            )
            table_data.append(
                [
                    stock_code,
                    stock_name,
                    stock_plates,
                    stock_current_price,
                    monitor_income_ratio,
                    stock_risk_level,
                    stock_focus_level,
                ]
            )

        # 返回表格数据
        return TableDataDto(
            table_header=[
                "股票代码",
                "股票名称",
                "股票领域",
                "股票当前价",
                "当前盈亏比例",
                "当前风险等级",
                "当前关注等级",
            ],
            table_data=table_data,
            table_item_fun=[{"查看详情": self.show_table_detail}],
        )

    def generate_stock_json(
        self, stock_list: List[AntMonitorStock], score_type: str = "focus"
    ) -> List[Dict]:
        """
        按照 stock_plates 分类生成 JSON 对象，根据类型选择使用 stock_focus_level 或 stock_risk_level。

        Args:
            stock_list (List[AntMonitorStock]): 股票对象列表。
            score_type (str): 决定使用的分数类型，"focus" 取 stock_focus_level，"risk" 取 stock_risk_level。

        Returns:
            List[Dict]: 分类后的 JSON 对象。
        """
        # 检查 score_type 是否有效
        if score_type not in {"focus", "risk"}:
            raise ValueError("score_type 必须为 'focus' 或 'risk'")

        # 分数字段名
        score_field = (
            "stock_focus_level" if score_type == "focus" else "stock_risk_level"
        )

        # 用于存储分类后的数据
        categorized_data = defaultdict(list)

        # 遍历股票数据，按 stock_plates 分类
        for stock in stock_list:
            # 使用 'common' 作为默认分类
            plate_name = stock.stock_plates if stock.stock_plates else "common"
            categorized_data[plate_name].append(stock)

        # 构建目标 JSON 数据
        result = []
        for plate, stocks in categorized_data.items():
            # 分类总分
            total_score = sum(getattr(stock, score_field) or 0 for stock in stocks)

            # 构建分类数据
            children = [
                {
                    "value": getattr(stock, score_field) or 0,
                    "name": stock.stock_name or "Unknown",
                }
                for stock in stocks
            ]

            result.append(
                {
                    "value": total_score,
                    "name": plate,
                    "children": children,
                }
            )

        return result

    def get_risk_level_description(self, risk_level: int) -> str:
        """
        根据风险等级返回描述。
        :param risk_level: 风险等级
        :return: 风险等级描述
        """
        if risk_level is None:
            return "未知"
        return f"{risk_level}"

    def get_focus_level_description(self, risk_level: int) -> str:
        """
        根据风险等级返回描述。
        :param risk_level: 风险等级
        :return: 风险等级描述
        """
        if risk_level is None:
            return "未知"
        return f"{risk_level}"

    def show_table_detail(self, stock_code: str):
        """
        查看股票详情（示例方法，具体逻辑可实现）。
        :param stock_code: 股票代码
        """
        AntLogger.info(f"查看股票详情: {stock_code}")
